#include "include/lh_nonstandard_485_drive.h"
#include "include/paramnonstandard485.h"
#include "include/transmissioninter.h"
// LH_NonStandard_485_Drive::LH_NonStandard_485_Drive( QObject* parent ) : QObject( parent ) {
//    this->config_name = "./config/";
//    qRegisterMetaType< DriveErrorState >( "DriveErrorState" );
//    qRegisterMetaType< DriveErrorState >( "DriveErrorState&" );
//    qRegisterMetaType< TransmissionInter::TransMissionData >( "TransmissionInter::TransMissionData" );
//    qRegisterMetaType< TransmissionInter::TransMissionData >( "TransmissionInter::TransMissionData&" );
//}

LH_NonStandard_485_Drive::LH_NonStandard_485_Drive( QObject* parent, const QString config_name ) : QObject( parent ), config_name( config_name ) {
    qRegisterMetaType< DriveErrorState >( "DriveErrorState" );
    qRegisterMetaType< DriveErrorState >( "DriveErrorState&" );
    qRegisterMetaType< TransmissionInter::TransMissionData >( "TransmissionInter::TransMissionData" );
    qRegisterMetaType< TransmissionInter::TransMissionData >( "TransmissionInter::TransMissionData&" );
    paramNonStandard = new ParamNonStandard485();
    qDebug() << "LH_NonStandard_485_Drive:" << config_name;
    paramNonStandard->readParam( config_name );
    paramNonStandard->printParam();
    readList   = new QList< QByteArray >();
    writerList = new QList< QByteArray >();
}

LH_NonStandard_485_Drive::~LH_NonStandard_485_Drive() {
    if ( timer ) { timer->stop(); }
    delete timer;
    if ( transmissionInter ) { delete transmissionInter; }
    if ( batterInter ) { delete batterInter; }
    if ( shutterDoorInter ) { delete shutterDoorInter; }
    if ( serialPort && serialPort->isOpened() ) { serialPort->SerialPort()->close(); }
    delete serialPort;
    if ( writerList ) {
        writerList->clear();
        delete writerList;
    }
    if ( readList ) {
        readList->clear();
        delete readList;
    }
    if ( paramNonStandard ) delete paramNonStandard;
}

void LH_NonStandard_485_Drive::onTransmissionControl( const TransmissionInter::TransMissionData transMissionData ) {
    if ( transmissionInter ) { transmissionInter->onAddWriteData( writerList, transMissionData ); }
    else {
        TransmissionInter::TransMissionData data;
        data.state        = TransmissionInter::TransMissionState::Error;
        data.trans_action = transMissionData.trans_action;
        emit sigTransmissionState( data );
        emit sigErrorinfo( Trans_Drive_Error, "传输驱动未初始化完成!" );
    }
}

void LH_NonStandard_485_Drive::onShutterDoorControl( const TransmissionInter::TransMissionData transMissionData ) {
    if ( shutterDoorInter ) { shutterDoorInter->onAddWriteData( writerList, transMissionData ); }
    else {
        TransmissionInter::TransMissionData data;
        data.state        = TransmissionInter::TransMissionState::Error;
        data.trans_action = transMissionData.trans_action;
        emit sigTransmissionState( data );
        emit sigErrorinfo( Shurt_Drive_error, "卷帘门驱动未初始化完成!" );
    }
}

QString LH_NonStandard_485_Drive::GET_Value( TransmissionInter::EnumBattery Enum ) {
    if ( batterInter ) return batterInter->GET_Value( Enum );
    return "电池未初始化";
}

bool LH_NonStandard_485_Drive::getFaultState( QString& result ) {
    if ( batterInter ) return batterInter->getFaultState( result );
    return false;
}

short LH_NonStandard_485_Drive::Reinterpret( char L, char H ) {
    if ( batterInter ) return batterInter->Reinterpret( L, H );
    return 0;
}

int LH_NonStandard_485_Drive::Reinterpret( char L, char H8, char H16, char H24 ) {
    if ( batterInter ) return batterInter->Reinterpret( L, H8, H16, H24 );
    return 0;
}

ParamNonStandard485* LH_NonStandard_485_Drive::getParamNonStandar() {
    if ( paramNonStandard ) return paramNonStandard;
    return nullptr;
}

void LH_NonStandard_485_Drive::sltOnInit() {

    onTransInterInit();
    qDebug() << "LH_NonStandard_485_Drive::sltOnInit" << paramNonStandard->getSerialConfig()->SerialPortNameParameter << paramNonStandard->getSerialConfig()->SerialBaudRateParameter;
    serialPort = new SerialPortObj( config_name, paramNonStandard->getSerialConfig()->SerialPortNameParameter, paramNonStandard->getSerialConfig()->SerialBaudRateParameter );

    connect( serialPort, SIGNAL( sigReadData( QByteArray ) ), this, SLOT( sltOnRecvieData( QByteArray ) ) );
    connect( this, SIGNAL( sigSendData( SerialPortObj*, QByteArray ) ), serialPort, SLOT( sltSendData( SerialPortObj*, QByteArray ) ) );

    serialPort->init( false, 300 );
    if ( serialPort->isOpened() ) {
        timer = new QTimer();
        connect( timer, SIGNAL( timeout() ), this, SLOT( sltOnTimer() ) );
        timer->start( paramNonStandard->getSerialConfig()->SerialFrequency );
    }
    else {
        emit sigErrorinfo( DriveErrorState::Serial_Open_Error, tr( "打开串口失败" ) );
    }
}

void LH_NonStandard_485_Drive::sltOnTimer() {
    if ( !serialPort ) { return; }
    static bool isWrite;
    static int  tiem_recevie_read;
    tiem_recevie_read += paramNonStandard->getSerialConfig()->SerialFrequency;
    //写
    if ( writerList && writerList->size() > 0 && tiem_recevie_read >= waiter_recevie_msec ) {
        isWrite = true;
        //        qDebug() << "Serial writer send data:" << writerList->at( 0 ).toHex();
        tiem_recevie_read = 0;
        onSendSerialData( writerList->takeAt( 0 ) );
    }
    //传输状态采集
    static int time_transmission_read;
    if ( ( paramNonStandard->getTransmissionConfig()->Car_OPEN_Transmission == 1 )
         && ( ++time_transmission_read >= ( paramNonStandard->getTransmissionConfig()->TransmissionReadFrequency / paramNonStandard->getSerialConfig()->SerialFrequency ) ) ) {
        //        qDebug() << config_name << " :transmission read NonStandard data";
        transmissionInter->onAddReadData( readList, paramNonStandard->getTransmissionConfig()->Car_UP_Left_StatID );
        transmissionInter->onAddReadData( readList, paramNonStandard->getTransmissionConfig()->Car_UP_Right_StatID );
        transmissionInter->onAddReadData( readList, paramNonStandard->getTransmissionConfig()->Car_Down_Left_StatID );
        transmissionInter->onAddReadData( readList, paramNonStandard->getTransmissionConfig()->Car_Down_Right_StatID );
        time_transmission_read = 0;
    }
    //电池数据采集
    static int time_batery_read;
    if ( ( paramNonStandard->getBatterConfig()->Car_OPEN_Batter == 1 )
         && ( ++time_batery_read >= ( paramNonStandard->getBatterConfig()->BatteryReadFrequency / paramNonStandard->getSerialConfig()->SerialFrequency ) ) ) {
        time_batery_read = 0;
        batterInter->onAddReadData( readList, paramNonStandard->getBatterConfig()->Car_Battery_StartID );
    }
    static int time_shurt_door_read;
    if ( ( paramNonStandard->getShurtDoorConfig()->Car_OPEN_ShutterDoor == 1 )
         && ( ++time_shurt_door_read >= ( paramNonStandard->getShurtDoorConfig()->ShutterDoorReadFrequency / paramNonStandard->getSerialConfig()->SerialFrequency ) ) ) {
        time_shurt_door_read = 0;
        shutterDoorInter->onAddReadData( readList, paramNonStandard->getShurtDoorConfig()->Car_ShutterDoor_StatID );
    }
    //读数据,写优先，不同时读写
    if ( !isWrite && readList && readList->size() > 0 && tiem_recevie_read >= waiter_recevie_msec ) {
        tiem_recevie_read = 0;
        //        qDebug() << config_name << "Serial read send data:" << readList->at( 0 ).toHex();
        onSendSerialData( readList->takeAt( 0 ) );
    }
    isWrite = false;
}

void LH_NonStandard_485_Drive::sltOnRecvieData( const QByteArray& data ) {
    char device_id = data.at( 0 );
    if ( transmissionInter && ( device_id == paramNonStandard->getTransmissionConfig()->Car_UP_Left_StatID || device_id == paramNonStandard->getTransmissionConfig()->Car_UP_Right_StatID
                                || device_id == paramNonStandard->getTransmissionConfig()->Car_Down_Right_StatID || device_id == paramNonStandard->getTransmissionConfig()->Car_Down_Left_StatID ) ) {
        transmissionInter->onReadHandler( data );
    }
    if ( batterInter && device_id == paramNonStandard->getBatterConfig()->Car_Battery_StartID ) { batterInter->onReadHandler( data ); }
    if ( shutterDoorInter && device_id == paramNonStandard->getShurtDoorConfig()->Car_ShutterDoor_StatID ) { shutterDoorInter->onReadHandler( data ); }
}

void LH_NonStandard_485_Drive::sltOnTransInterState( const TransmissionInter::TransMissionData& data ) {
    emit sigTransmissionState( data );
    if ( data.state == TransmissionInter::TransMissionState::Error ) { emit sigErrorinfo( Trans_Drive_Error, tr( "驱动器报警" ) ); }
}

void LH_NonStandard_485_Drive::sltOnTransInterError( const uchar& deviceAddress ) {
    emit sigTransmissionError( deviceAddress );
    emit sigErrorinfo( Trans_Drive_Error, tr( "驱动器：%1报警" ).arg( deviceAddress ) );
}

void LH_NonStandard_485_Drive::onTransInterInit() {
    if ( paramNonStandard->getTransmissionConfig()->Car_OPEN_Transmission == 1 ) {
#ifdef DMK_Transmssion_
        transmissionInter = new DMK_Transmssion( nullptr, paramNonStandard );
#endif
#ifdef TB_Transmssion_
        transmissionInter = new TB_Transmssion( nullptr, paramNonStandard );
#endif
        if ( transmissionInter ) {
            connect( transmissionInter, &TransmissionInter::sigTransmissionError, this, &LH_NonStandard_485_Drive::sltOnTransInterError );
            connect( transmissionInter, &TransmissionInter::sigTransmissionState, this, &LH_NonStandard_485_Drive::sltOnTransInterState );
            transmissionInter->init( writerList, paramNonStandard->getTransmissionConfig()->Car_UP_Left_StatID );
            transmissionInter->init( writerList, paramNonStandard->getTransmissionConfig()->Car_UP_Right_StatID );
            transmissionInter->init( writerList, paramNonStandard->getTransmissionConfig()->Car_Down_Left_StatID );
            transmissionInter->init( writerList, paramNonStandard->getTransmissionConfig()->Car_Down_Right_StatID );
        }
    }
    if ( paramNonStandard->getBatterConfig()->Car_OPEN_Batter == 1 ) {
        batterInter = new Battery_Transmssion( nullptr, paramNonStandard );
        if ( batterInter ) batterInter->init( writerList, paramNonStandard->getBatterConfig()->Car_Battery_StartID );
    }
    if ( paramNonStandard->getShurtDoorConfig()->Car_OPEN_ShutterDoor == 1 ) {
        shutterDoorInter = new ReTe_Transmision( nullptr, paramNonStandard );
        if ( shutterDoorInter ) shutterDoorInter->init( writerList, paramNonStandard->getShurtDoorConfig()->Car_ShutterDoor_StatID );
    }
}

void LH_NonStandard_485_Drive::onSetWaiterMsec( const QByteArray& data ) {
    char device_id = data[ 0 ];
    if ( device_id == paramNonStandard->getBatterConfig()->Car_Battery_StartID ) {
        waiter_recevie_msec = paramNonStandard->getBatterConfig()->BatteryWaitertimer;
        serialPort->setMsec( waiter_recevie_msec );
    }
    if ( device_id == paramNonStandard->getTransmissionConfig()->Car_UP_Left_StatID || device_id == paramNonStandard->getTransmissionConfig()->Car_UP_Right_StatID
         || device_id == paramNonStandard->getTransmissionConfig()->Car_Down_Right_StatID || device_id == paramNonStandard->getTransmissionConfig()->Car_Down_Left_StatID ) {
        waiter_recevie_msec = paramNonStandard->getTransmissionConfig()->TransmissionWaiterTimer;
        serialPort->setMsec( waiter_recevie_msec );
    }
    if ( device_id == paramNonStandard->getShurtDoorConfig()->Car_ShutterDoor_StatID ) {
        waiter_recevie_msec = paramNonStandard->getShurtDoorConfig()->ShutterDoorWaiterTimer;
        serialPort->setMsec( waiter_recevie_msec );
    }
}

void LH_NonStandard_485_Drive::onSendSerialData( const QByteArray& data ) {
    //设置本次写等待报文返回的时间
    onSetWaiterMsec( data );
    emit sigSendData( serialPort, data );
}
